from insts.inst import NoOperandInstruction, Index8Instruction
from jthread.frame import JFrame


class STORE_CONST(NoOperandInstruction):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'int'
        self.index = 0

    def execute(self, frame: JFrame):
        stack = frame.getOperandStack()
        localVars = frame.getLocalVars()
        if self.kind == 'int':
            localVars.setInt(self.index, stack.popInt())
        elif self.kind == 'float':
            localVars.setFloat(self.index, stack.popFloat())
        elif self.kind == 'double':
            localVars.setDouble(self.index, stack.popDouble())
        elif self.kind == 'long':
            localVars.setLong(self.index, stack.popLong())
        else:
            localVars.setRef(self.index, stack.popRef())


class STOTRE(Index8Instruction):

    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'int'

    def execute(self, frame: JFrame):
        stack = frame.getOperandStack()
        localVars = frame.getLocalVars()
        if self.kind == 'int':
            localVars.setInt(self.index, stack.popInt())
        elif self.kind == 'float':
            localVars.setFloat(self.index, stack.popFloat())
        elif self.kind == 'double':
            localVars.setDouble(self.index, stack.popDouble())
        elif self.kind == 'long':
            localVars.setLong(self.index, stack.popLong())
        else:
            localVars.setRef(self.index, stack.popRef())


class DSTORE_0(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'double'
        self.index = 0


class DSTORE_1(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'double'
        self.index = 1


class DSTORE_2(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'double'
        self.index = 2


class DSTORE_3(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'double'
        self.index = 3


class FSTORE_0(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'float'
        self.index = 0


class FSTORE_1(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'float'
        self.index = 1


class FSTORE_2(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'float'
        self.index = 2


class FSTORE_3(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'float'
        self.index = 3


class ISTORE_0(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'int'
        self.index = 0


class ISTORE_1(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'int'
        self.index = 1


class ISTORE_2(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'int'
        self.index = 2


class ISTORE_3(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'int'
        self.index = 3


class LSTORE_0(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'long'
        self.index = 0


class LSTORE_1(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'long'
        self.index = 1


class LSTORE_2(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'long'
        self.index = 2


class LSTORE_3(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'long'
        self.index = 3


class ASTORE_0(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'ref'
        self.index = 0


class ASTORE_1(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'ref'
        self.index = 1


class ASTORE_2(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'ref'
        self.index = 2


class ASTORE_3(STORE_CONST):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'ref'
        self.index = 3


class ISTORE(STOTRE):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'int'


class LSTORE(STOTRE):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'long'


class FSTORE(STOTRE):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'float'


class DSTORE(STOTRE):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind = 'double'


class ASTORE(STOTRE):
    def __init__(self, opcode):
        super().__init__(opcode)
        self.kind ='ref'